package com.iwhalecloud.bss.kite.cucc.service.inst;

import com.iwhalecloud.bss.kite.client.api.scene.operate.IOperateSceneAdditionalOfferInstService;
import com.iwhalecloud.bss.kite.client.api.scene.query.IQuerySceneAccessProdInstService;
import com.iwhalecloud.bss.kite.client.api.scene.query.IQuerySceneCommonService;
import com.iwhalecloud.bss.kite.client.api.scene.query.IQuerySceneMainOfferInstService;
import com.iwhalecloud.bss.kite.client.api.scene.query.IQuerySceneService;
import com.iwhalecloud.bss.kite.client.dto.DataResult;
import com.iwhalecloud.bss.kite.client.dto.inst.OfferInstDTO;
import com.iwhalecloud.bss.kite.client.dto.inst.ProdInstDTO;
import com.iwhalecloud.bss.kite.client.vo.scene.ProdSubOfferVO;
import com.iwhalecloud.bss.kite.common.constant.ErrorConsts;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.cucc.client.api.inst.IAdditionalOfferInstService;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferCache;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferRelCache;
import com.iwhalecloud.bss.kite.dataservice.cache.ProductCache;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.Offer;
import com.iwhalecloud.bss.kite.manager.api.IOperateSceneInstService;
import com.iwhalecloud.bss.kite.manager.enums.InstType;
import com.iwhalecloud.bss.kite.manager.inst.KiteSceneInst;
import com.ztesoft.bss.base.staticdata.CoreDataPublic;
import com.ztesoft.bss.common.bo.LoginInfo;
import com.ztesoft.bss.common.util.ContextUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Objects;

@Service
public class AdditionalOfferInstService implements IAdditionalOfferInstService {

	@Autowired
    private IQuerySceneCommonService querySceneCommonService;

    @Autowired
    private IOperateSceneAdditionalOfferInstService operateSceneAdditionalOfferInstService;

    @Autowired
    private IQuerySceneMainOfferInstService querySceneMainOfferInstService;

    @Autowired
    private IQuerySceneAccessProdInstService querySceneAccessProdInstService;

    @Autowired
    private IQuerySceneService querySceneService;

    @Autowired
    private IOperateSceneInstService operateSceneInstService;

	@Override
	public DataResult<ProdSubOfferVO> addAdditionalOffer(String sceneInstId, String prodInstId, String offerInstId, String offerId, String custId,
			String type, boolean addOnly) {
        LoginInfo loginInfo = ContextUtil.getLoginInfo();
        String staffId = loginInfo.getUserInfo().getUserId() + "";

        checkOfferStatus(offerId);

        //特殊处理,规则设置触发条件 START
        operateSceneInstService.putExtParameter(sceneInstId, KeyConsts.KEY_DISABLE_RULE_ADDITIONAL_OFFER, KeyConsts.IFTRUE_F);

        //产品约束的可选包
        if (KeyConsts.ADDITIONAL_PRODUCT_TYPE.equals(type)) {
            ProdInstDTO prodInstDTO = querySceneAccessProdInstService.getSceneProdInstByProdInstId(sceneInstId, prodInstId, custId).getResultObject();
            checkOfferRel(ProductCache.get(prodInstDTO.getProdId()).getBaseOfferId(), offerId);

            if (addOnly) {
                operateSceneAdditionalOfferInstService
                    .addAdditionalOfferOfProduct(sceneInstId, prodInstId, offerId, custId, staffId, true).getResultObject();
            }
            else {
                operateSceneAdditionalOfferInstService
                    .addAdditionalOfferOfProduct(sceneInstId, prodInstId, offerId, custId, staffId).getResultObject();
            }

        }
        else if (KeyConsts.ADDITIONAL_OFFER_TYPE.equals(type)) {
            OfferInstDTO offerInst = getContractOfferInstForOffer(sceneInstId, custId, offerId);
            if (offerInst == null) {
                offerInst = querySceneMainOfferInstService.getSceneMainOfferInstByProdInstId(sceneInstId, prodInstId, custId).getResultObject();
            }
            if (offerInst == null) {
                offerInst = querySceneCommonService
                    .getSceneOfferInstByOfferInstId(sceneInstId, offerInstId, custId).getResultObject();
            }
            offerInstId = offerInst.getOfferInstId();

            checkOfferRel(offerInst.getOfferId(), offerId);
            operateSceneAdditionalOfferInstService
                .addAdditionalOffer(sceneInstId, offerInstId, prodInstId, offerId, custId, staffId).getResultObject();
        }
        //特殊处理,规则设置触发条件 END;
        operateSceneInstService.putExtParameter(sceneInstId, KeyConsts.KEY_DISABLE_RULE_ADDITIONAL_OFFER, KeyConsts.IFTRUE_T);

        return null;
	}

	/**
     * 校验可选包是否失效
     * @param offerId
     */
    private void checkOfferStatus(String offerId) {
        Offer offer = OfferCache.get(offerId);
        if (offer == null || !StringUtils
            .equalsAny(offer.getStatusCd(), CoreDataPublic.PUB_C_0001_1000, CoreDataPublic.PUB_C_0012_1400)) {
            ErrorConsts.OFFER_STATUS_INVALID.throwOut(offerId);
        }
    }

	/**
     * 校验销售品关系
     * @param aOfferId
     * @param zOfferId
     */
    private void checkOfferRel(String aOfferId, String zOfferId) {
        //在controller校验，5G专区可选包是没有关系的也能订购，因此不能在标准服务校验
        /*if (!OfferUtils.hasOfferRel(aOfferId, zOfferId)) {
            ErrorConsts.OFFER_RELATION_NOT_FOUND
                .throwOut(Optional.ofNullable(OfferCache.get(aOfferId)).map(Offer::getOfferName).orElse(""), aOfferId,
                    Optional.ofNullable(OfferCache.get(zOfferId)).map(Offer::getOfferName).orElse(""), zOfferId);
        }*/
    }

    private OfferInstDTO getContractOfferInstForOffer(String sceneInstId, String custId, String offerId) {
        KiteSceneInst kiteSceneInst = querySceneService.getSceneInst(sceneInstId);
        if (kiteSceneInst.getRootInstType() == InstType.PROMOTION_OFFER_INST) {
            OfferInstDTO offerInstDTO = querySceneCommonService.getSceneOfferInstByOfferInstId(sceneInstId, kiteSceneInst.getRootInstId(), custId).getResultObject();
            if (offerInstDTO != null && KeyConsts.OFFER_SYS_TYPE_1599.equals(OfferCache.get(offerInstDTO.getOfferId()).getOfferSysType())) {
                return OfferRelCache.get(offerInstDTO.getOfferId()).stream().anyMatch(t -> Objects.equals(t.getzOfferId(), offerId)) ? offerInstDTO : null;
            }
        }
        return null;
    }
}
